package controlador;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.border.LineBorder;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import modelo.Cliente;
import modelo.Compra;
import modelo.Cuenta;
import modelo.Detalle_Compra;
import modelo.Detalle_Venta;
import modelo.Empresa;
import modelo.Pago;
import modelo.Venta;

import org.hibernate.criterion.Restrictions;

import rep.Estado_Cuenta_Compras_Cliente;
import rep.Estado_Cuenta_General;
import rep.Estado_Cuenta_Pagos_Cliente;
import rep.Estado_Cuenta_Ventas_Cliente;

import bean.Documento;
import bean.TablaPlus;

import dao.imp.Base_DatosDAO;

import vista.frmConsultarDeudaCliente;

public class ControladorConsultarDeudaCliente implements ActionListener{
	private frmConsultarDeudaCliente frmConsultaDeuda;
	private final static String title = "SACFRE/Consulta Deuda Cliente";
	private int mensaje_error;
	private int mensaje_information;
	private int mensaje_question;
	private int si;
	private Cliente cliente;
	private Cuenta cuenta;
	private Empresa empresa;
	public final static int TAB_PAGO = 0;
	public final static int TAB_VENTA = 1;
	public final static int TAB_COMPRA = 2;
	
	public ControladorConsultarDeudaCliente() {
		super();
		frmConsultaDeuda = new frmConsultarDeudaCliente(this);
		frmConsultaDeuda.setVisible(true);
		frmConsultaDeuda.setLocationRelativeTo(null);
		frmConsultaDeuda.Agregar_Escuchadores(this);
		mensaje_error=frmConsultaDeuda.getMensaje().ERROR_MESSAGE;
		mensaje_information=frmConsultaDeuda.getMensaje().INFORMATION_MESSAGE;
		mensaje_question=frmConsultaDeuda.getMensaje().YES_NO_OPTION;
		si=frmConsultaDeuda.getMensaje().YES_OPTION;
		Base_DatosDAO conexion = new Base_DatosDAO();
		this.empresa = (Empresa)conexion.findByProperty(Empresa.class,Restrictions.eq("estatus", 'a')).get(0);
	}

	@Override
	public void actionPerformed(ActionEvent evento) {
		String actionComand = evento.getActionCommand();
		if(actionComand.equals("")){
			try {
				Limpiar_Tablas();
				Cargar_Datos_Cliente();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else if (actionComand.equals("Cancelar")){
			Cancelar();
		}else if (actionComand.equals("Pagar")){
			Pagar();
		}else if (actionComand.equals("Ver Detalle")){
			try {
				Mostrar_Detalle();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else if (actionComand.equals("Exportar")){
			iniciarProcesoImpresion();
		}
	}

	private void iniciarProcesoImpresion() {
		if (this.cuenta==null){
			JOptionPane.showMessageDialog(frmConsultaDeuda, "Debe Seleccionar al menos una cuenta!");
		}else{
			List<Documento> documentos = crearDocumentosImpresion();
			if (documentos.size()>0){
				ControladorImpresora.getInstacia(documentos);
			}else {
				JOptionPane.showMessageDialog(frmConsultaDeuda, "Esta Cueta no posee documentos para imprimir", title, JOptionPane.WARNING_MESSAGE);
			}
			
		}
	}

	private List<Documento> crearDocumentosImpresion() {
		List<Documento> documentos = new ArrayList<Documento>();
		if (cuenta.getVentas().size()>0){
			Estado_Cuenta_Ventas_Cliente ventas = new Estado_Cuenta_Ventas_Cliente(cuenta,
													"/home/adriana/Escritorio/SACFRE/rep/jasper/estado_cuenta_ventas_cliente.jasper", 
													"/home/adriana/Escritorio/SACFRE/rep/imp/","/home/adriana/Escritorio/SACFRE/rep/jasper/");
			documentos.add(ventas);
		}if (cuenta.getCompras().size()>0){
			Estado_Cuenta_Compras_Cliente compras = new Estado_Cuenta_Compras_Cliente(cuenta,
													"/home/adriana/Escritorio/SACFRE/rep/jasper/estado_cuenta_compras_cliente.jasper", 
													"/home/adriana/Escritorio/SACFRE/rep/imp/","/home/adriana/Escritorio/SACFRE/rep/jasper/");
			documentos.add(compras);
		}if (cuenta.getPagos().size()>0){
			Estado_Cuenta_Pagos_Cliente pagos = new Estado_Cuenta_Pagos_Cliente(cuenta,
													"/home/adriana/Escritorio/SACFRE/rep/jasper/estado_cuenta_pagos_cliente.jasper", 
													"/home/adriana/Escritorio/SACFRE/rep/imp/","/home/adriana/Escritorio/SACFRE/rep/jasper/");
			documentos.add(pagos);
		}if ((cuenta.getVentas().size()>0)||(cuenta.getCompras().size()>0)||(cuenta.getPagos().size()>0)){
			Estado_Cuenta_General general = new Estado_Cuenta_General(cuenta,
												"/home/adriana/Escritorio/SACFRE/rep/jasper/estado_cuenta_general.jasper",
												"/home/adriana/Escritorio/SACFRE/rep/imp/","/home/adriana/Escritorio/SACFRE/rep/jasper/");
			documentos.add(general);
		}
		return documentos;
	}

	private void Mostrar_Detalle() throws ParseException {
		int tab_seleccionado = this.frmConsultaDeuda.getTabpanel().getSelectedIndex();
		switch (tab_seleccionado) {
			case TAB_PAGO:	frmConsultaDeuda.getMensaje().showMessageDialog(frmConsultaDeuda, "Disculpe pero los pagos no poseen Detalles!", title, this.mensaje_information);break;
			case TAB_VENTA:Mostrar_Detalle_Venta();break;
			case TAB_COMPRA:Mostrar_Detalle_Compra();break;
			default:break;
		}
	}
	

	private void Mostrar_Detalle_Compra() throws ParseException {
		if (esNumeroFilaSeleccionadaValido(TAB_COMPRA)){
			Base_DatosDAO conexion = new Base_DatosDAO();
			Compra compra = (Compra) conexion.findByProperty(Compra.class, Restrictions.idEq(Integer.parseInt((String) frmConsultaDeuda.getTbcompra().getTabla().getValueAt(frmConsultaDeuda.getTbcompra().getTabla().getSelectedRow(), 1)))).get(0);
			JFrame detalle = new JFrame("Compra N�:"+compra.getNumero()+" Fecha: "+compra.getFecha());
			
			detalle.setSize(750, 300);
			TablaPlus tabla = new TablaPlus();
			String[] columnas = { "Fresa","Cestas"," Precio/Cesta","Kilos","Precio/kg","Total" };
			detalle.add(tabla);
			tabla.setBounds(0, 0, 750, 300);
			tabla.setTablaPlus(columnas);
			tabla.setEnabled(false);
			tabla.setBorder(new LineBorder(new java.awt.Color(0,0,0), 1, false));
			tabla.setFont(new java.awt.Font("FreeSerif",1,14));
			List<Detalle_Compra> detalles = compra.getFresas_compra();
			for(int i=0;i<detalles.size();i++){
				String[] fila={detalles.get(i).getFresa().getNombre(),String.valueOf(detalles.get(i).getCantidad_cestas()),String.valueOf(detalles.get(i).getPrecio_cesta()),String.valueOf(detalles.get(i).getCantidad_kg()),String.valueOf(detalles.get(i).getPrecio_kg()),String.valueOf(detalles.get(i).MontoTotalDetalle())};
				tabla.AgregarFila(fila);
			}
			detalle.setLocationRelativeTo(frmConsultaDeuda);
			detalle.setVisible(true);
			detalle.setResizable(false);
		}else{
			frmConsultaDeuda.getMensaje().showMessageDialog(frmConsultaDeuda, "Debe seleccionar UN detalle solamente", title, this.mensaje_information);
		}
	}

	private void Mostrar_Detalle_Venta() throws ParseException {
		if (esNumeroFilaSeleccionadaValido(TAB_VENTA)){
			Base_DatosDAO conexion = new Base_DatosDAO();
			Venta venta = (Venta) conexion.findByProperty(Venta.class, Restrictions.idEq(Integer.parseInt((String) frmConsultaDeuda.getTbventas().getTabla().getValueAt(frmConsultaDeuda.getTbventas().getTabla().getSelectedRow(), 1)))).get(0);
			JFrame detalle = new JFrame("Venta N�:"+venta.getNumero()+" Cliente: "+venta.getCliente().getApellido()+" "+venta.getCliente().getNombre()+" Fecha: "+venta.getFecha());
			detalle.setSize(750, 300);
			TablaPlus tabla = new TablaPlus();
			String[] columnas = { "Producto"," Precio "," Cantidad ","Unidad","Total" };
			detalle.add(tabla);
			tabla.setBounds(0, 0, 750, 300);
			tabla.setTablaPlus(columnas);
			tabla.setEnabled(false);
			tabla.setBorder(new LineBorder(new java.awt.Color(0,0,0), 1, false));
			tabla.setFont(new java.awt.Font("FreeSerif",1,14));
			List<Detalle_Venta> detalles = venta.getDetalle_venta();
			for(int i=0;i<detalles.size();i++){
				String[] fila={detalles.get(i).getProducto().getNombre(),String.valueOf(detalles.get(i).getPrecio()),String.valueOf(detalles.get(i).getCantidad_producto()),detalles.get(i).getProducto().getUnidad().getNombre(),String.valueOf(detalles.get(i).MontoDetalle_Venta())};
				tabla.AgregarFila(fila);
			}
			detalle.setLocationRelativeTo(frmConsultaDeuda);
			detalle.setVisible(true);
			detalle.setResizable(false);
		}else{
			frmConsultaDeuda.getMensaje().showMessageDialog(frmConsultaDeuda, "Debe seleccionar UN detalle solamente", title, this.mensaje_information);
		}
	}

	public boolean esNumeroFilaSeleccionadaValido(int tab){
		int numero_filas_seleccionadas=-1;
		switch (tab){
			case TAB_PAGO: numero_filas_seleccionadas=this.frmConsultaDeuda.getTbpago().getTabla().getSelectedRowCount();break;
			case TAB_VENTA:numero_filas_seleccionadas=this.frmConsultaDeuda.getTbventas().getTabla().getSelectedRowCount();break;
			case TAB_COMPRA:numero_filas_seleccionadas=this.frmConsultaDeuda.getTbcompra().getTabla().getSelectedRowCount();break;
		}
		return (numero_filas_seleccionadas==1);
	}

	private void Pagar() {
		if (this.cliente==null){
			frmConsultaDeuda.getMensaje().showMessageDialog(frmConsultaDeuda, "Debe asociar un cliente al pago", title, mensaje_error);
		}else{
			new ControladorGestionarPago(cliente);
			frmConsultaDeuda.dispose();
		}
	}

	private void Cargar_Datos_Cliente() throws ParseException {
		if (frmConsultaDeuda.getTxtnumero().getText().equals("")){
			frmConsultaDeuda.getMensaje().showMessageDialog(frmConsultaDeuda, "Debe indicar un cliente", title, this.mensaje_error);
		}else{
			Cliente cliente = this.empresa.Buscar_Cliente(frmConsultaDeuda.getCmbidentificacion().getSelectedItem()+frmConsultaDeuda.getTxtnumero().getText());
			if (cliente==null){
				frmConsultaDeuda.getMensaje().showMessageDialog(frmConsultaDeuda, "Cliente no se encuentra Registrado", title, this.mensaje_error);
			}else if (cliente.getEstatus()=='e'){
				if (frmConsultaDeuda.getMensaje().showConfirmDialog(frmConsultaDeuda, "El cliente se encuentra Inactivo, �Desea Reactivarlo?", title, mensaje_question)==this.si){
					this.empresa.Reactivar_Cliente(cliente);
					Cargar_Cuentas(cliente);
					this.cliente=cliente;
				}
			}else{
				Cargar_Cuentas(cliente);
				this.cliente=cliente;
			}
		}
	}

	private void Cargar_Cuentas(Cliente cliente) throws ParseException {
		this.frmConsultaDeuda.getTbcuentas().LimpiarTabla();
		List<Cuenta> cuentas = empresa.Buscar_Cuentas_Cliente(cliente);
		frmConsultaDeuda.getLblapellido2().setText(cliente.getApellido());
		frmConsultaDeuda.getLblnombre2().setText(cliente.getNombre());
		for (int i=0;i<cuentas.size();i++){
			String fecha = String.valueOf(cuentas.get(i).getFecha().toGMTString().substring(2, 6).replaceAll(" ", "")+"-"+cuentas.get(i).getFecha().toGMTString().substring(6, 11)).replaceAll(" ", "");
			String [] nuevafila = {cuentas.get(i).getId(),fecha,String.valueOf(cuentas.get(i).Calcular_Saldo())};
			frmConsultaDeuda.getTbcuentas().AgregarFila(nuevafila);
		}
	}
	
	public void jTable1MouseClicked(MouseEvent evt) throws ParseException {
		List<Cuenta> cuentas = empresa.Buscar_Cuentas_Cliente(this.cliente);
		Cuenta cuenta=null;
		String id="";int fila;
		for (int i=0;i<cuentas.size();i++){
			fila = this.frmConsultaDeuda.getTbcuentas().getTabla().getSelectedRow();
			id = (String) this.frmConsultaDeuda.getTbcuentas().getModelotabla().getValueAt(fila,0);
			if (cuentas.get(i).getId().equals(id)){
				cuenta = cuentas.get(i);
				break;
			}
		}
		this.cuenta=cuenta;
		Mostrar_Relacion_Cliente(cuenta);
	}
	private void Mostrar_Relacion_Cliente(Cuenta cuenta) throws ParseException {
		Limpiar_Tablas();
		Cargar_Tabla_Venta(cuenta.getVentas());
		Cargar_Tabla_Compra(cuenta.getCompras());
		Cargar_Pagos(cuenta.getPagos());
		Actualizar_Monto_Total(cuenta);
	}
	
	private void Actualizar_Monto_Total(Cuenta cuenta) throws ParseException {
		double total= cuenta.Calcular_Saldo();
		DecimalFormat tot = new DecimalFormat("###0. ##");
		try {
			total = tot.parse(tot.format(total)).doubleValue();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		DecimalFormat.getNumberInstance().setMaximumFractionDigits(2);
		frmConsultaDeuda.getLblmonto().setText(String.valueOf(total)+" Bsf");
	}

	private void Cargar_Pagos(List<Pago> pagos) {
		for (int i=0;i<pagos.size();i++){
			String [] nuevafila = {pagos.get(i).getFecha().toString(),String.valueOf(pagos.get(i).getNumero()),pagos.get(i).getConcepto(),String.valueOf(pagos.get(i).getMonto())};
			frmConsultaDeuda.getTbpago().AgregarFila(nuevafila);
		}
	}

	private void Cargar_Tabla_Compra(List<Compra> compras_Cliente) throws ParseException {
		for (int i=0;i<compras_Cliente.size();i++){
			String [] nuevafila = {compras_Cliente.get(i).getFecha().toString(),String.valueOf(compras_Cliente.get(i).getNumero()),compras_Cliente.get(i).getTipo_compra().getDescripcion(),String.valueOf(compras_Cliente.get(i).MontoPagar_Cliente())};
			frmConsultaDeuda.getTbcompra().AgregarFila(nuevafila);
		}
	}

	private void Cargar_Tabla_Venta(List<Venta> ventas_Cliente) throws ParseException {
		for (int i=0;i<ventas_Cliente.size();i++){
			String [] nuevafila = {ventas_Cliente.get(i).getFecha().toString(),String.valueOf(ventas_Cliente.get(i).getNumero()),String.valueOf(ventas_Cliente.get(i).MontoTotal_Venta())};
			frmConsultaDeuda.getTbventas().AgregarFila(nuevafila);
		}
	}

	private void Limpiar_Tablas() {
		this.frmConsultaDeuda.getTbcompra().LimpiarTabla();
		this.frmConsultaDeuda.getTbpago().LimpiarTabla();
		this.frmConsultaDeuda.getTbventas().LimpiarTabla();
	}

	private void Cancelar() {
		Limpiar_Tablas();
		this.frmConsultaDeuda.getTbcuentas().LimpiarTabla();
		frmConsultaDeuda.getLblapellido2().setText("");
		frmConsultaDeuda.getLblnombre2().setText("");
		frmConsultaDeuda.getCmbidentificacion().setSelectedItem("V-");
		frmConsultaDeuda.getTxtnumero().setText("");
		frmConsultaDeuda.getLblmonto().setText("0.0 Bsf");
		cliente=null;
	}
	
}
